package com.inspection.service.impl;

import com.google.common.collect.Lists;
import com.inspection.constant.MenuTypeEnum;
import com.inspection.dao.SysMenuDao;
import com.inspection.dao.SysRoleDao;
import com.inspection.dao.SysRoleMenuDao;
import com.inspection.dao.SysUserRoleDao;
import com.inspection.entity.*;
import com.inspection.model.dto.SysRoleDTO;
import com.inspection.model.dto.SysRoleQueryDTO;
import com.inspection.service.SysRoleService;
import com.inspection.support.AssertUtils;
import com.inspection.support.PageHelper;
import com.inspection.support.SortHelper;
import com.inspection.support.model.BusinessBaseException;
import com.inspection.support.model.MenuDataTree;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhaoqi
 * @since 2020-12-08
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleDao sysRoleDao;

    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;

    @Autowired
    private SysMenuDao sysMenuDao;

    @Autowired
    private SysUserRoleDao sysUserRoleDao;


    @Override
    public Page<SysRoleDO> pageSysRole(SysRoleQueryDTO page) {


        Sort sort = SortHelper.buildSort(page);
        PageHelper check = PageHelper.check(page.getPageNo(), page.getPageSize());
        Pageable pageable = PageRequest.of(check.getOffset(), check.getPageSize(), sort);

        return sysRoleDao.findAll((Specification<SysRoleDO>) (root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> predicates = Lists.newArrayList();

            if (!StringUtils.isEmpty(page.getRoleName())) {
                predicates.add(criteriaBuilder.like(root.get("roleName"),"%"+ page.getRoleName()+"%"));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, pageable);


    }

    @Override
    public SysRoleDO getSysRole(SysRoleQueryDTO query) {
        AssertUtils.nonNull(query.getId(),"id不能为空");
        Optional<SysRoleDO> roleOp = sysRoleDao.findById(query.getId());
        if (!roleOp.isPresent()) {
              throw new BusinessBaseException("权限不存在");
        }
        SysRoleDO role = roleOp.get();

        SysRoleMenuDO roleMenuQuery = new SysRoleMenuDO();
        roleMenuQuery.setRoleId(role.getId());

        List<SysRoleMenuDO> roleMenus = sysRoleMenuDao.findAll(Example.of(roleMenuQuery));
        if(CollectionUtils.isEmpty(roleMenus)){
            return role;
        }

        List<Long> menuIdList = roleMenus.stream().map(m -> m.getMenuId()).collect(Collectors.toList());


        List<SysMenuDO> menus = sysMenuDao.findAllById(menuIdList);


//        MenuDataTree.TreeNode rootNode = SysMenuServiceImpl.buildRootNode();
//
//        MenuDataTree dataTree = new MenuDataTree();
//        dataTree.setRootNode(rootNode);
//        dataTree.setTreeName("菜单");
//
//
//        //根据根结点循环获取下面的结点
//        Map<Long, List<SysMenuDO>> parentMap = menus.stream().collect(Collectors.groupingBy(SysMenuDO::getParentId));
//
//        SysMenuServiceImpl.findDeep(rootNode, parentMap);

        role.setMenuList(menus);


        return role;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveSysRole(SysRoleDTO save) {

        SysRoleDO roleDO = new SysRoleDO();
        BeanUtils.copyProperties(save, roleDO);
        roleDO.setCreateTime(new Date());
        sysRoleDao.saveAndFlush(roleDO);

        if (!CollectionUtils.isEmpty(save.getMenuIdList())) {

            for (Long menuId : save.getMenuIdList()) {
                SysRoleMenuDO roleMenu = new SysRoleMenuDO();
                roleMenu.setRoleId(roleDO.getId());
                roleMenu.setMenuId(menuId);
                sysRoleMenuDao.saveAndFlush(roleMenu);
            }

        }

        
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSysRole(SysRoleDTO update) {
        AssertUtils.nonNull(update.getId(),"id不能为空");
        Optional<SysRoleDO> roleOp = sysRoleDao.findById(update.getId());
        if (!roleOp.isPresent()) {
            throw new BusinessBaseException("权限不存在");
        }

        SysRoleDO roleUpdate =roleOp.get();
        roleUpdate.setRoleName(update.getRoleName());
        roleUpdate.setRemark(update.getRemark());
        sysRoleDao.saveAndFlush(roleUpdate);
        //删除原来的映射

        SysRoleMenuDO roleMenuQuery = new SysRoleMenuDO();
        roleMenuQuery.setRoleId(update.getId());
        List<SysRoleMenuDO> roleMenus = sysRoleMenuDao.findAll(Example.of(roleMenuQuery));
        if(!CollectionUtils.isEmpty(roleMenus)){
            sysRoleMenuDao.deleteInBatch(roleMenus);
        }
        if(!CollectionUtils.isEmpty(update.getMenuIdList())) {
            for (Long menuId : update.getMenuIdList()) {
                SysRoleMenuDO roleMenu = new SysRoleMenuDO();
                roleMenu.setRoleId(update.getId());
                roleMenu.setMenuId(menuId);
                sysRoleMenuDao.saveAndFlush(roleMenu);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delSysRole(SysRoleDTO del) {
        AssertUtils.nonNull(del.getId(),"id不能为空");
        Optional<SysRoleDO> roleOp = sysRoleDao.findById(del.getId());
        if (!roleOp.isPresent()) {
            throw new BusinessBaseException("权限不存在");
        }
        SysRoleDO sysRole = roleOp.get();
        sysRoleDao.delete(sysRole);


        //删除roleMenu
        SysRoleMenuDO roleMenuQuery = new SysRoleMenuDO();
        roleMenuQuery.setRoleId(sysRole.getId());
        List<SysRoleMenuDO> roleMenus = sysRoleMenuDao.findAll(Example.of(roleMenuQuery));
        if(!CollectionUtils.isEmpty(roleMenus)){
            sysRoleMenuDao.deleteInBatch(roleMenus);
        }

        //删除userRole
        SysUserRoleDO userRoleQuery = new SysUserRoleDO();
        userRoleQuery.setRoleId(sysRole.getId());
        List<SysUserRoleDO> userRoles = sysUserRoleDao.findAll(Example.of(userRoleQuery));
        if(!CollectionUtils.isEmpty(userRoles)){
            sysUserRoleDao.deleteInBatch(userRoles);
        }



    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDelSysRole(SysRoleDTO del) {
        AssertUtils.nonNull(del.getIdList(),"idList不能为空");
        List<SysRoleDO> roles = sysRoleDao.findAllById(del.getIdList());
        if (CollectionUtils.isEmpty(roles)) {
            throw new BusinessBaseException("角色不存在");
        }
        sysRoleDao.deleteInBatch(roles);

        List<Long> roleIdList = roles.stream().map(r -> r.getId()).collect(Collectors.toList());



        List<SysRoleMenuDO> roleMenus = sysRoleMenuDao.findAllByRoleIdIn(roleIdList);
        if(!CollectionUtils.isEmpty(roleMenus)){
            sysRoleMenuDao.deleteInBatch(roleMenus);
        }

        //删除userRole

        List<SysUserRoleDO> userRoles = sysUserRoleDao.findAllByRoleIdIn(roleIdList);
        if(!CollectionUtils.isEmpty(userRoles)){
            sysUserRoleDao.deleteInBatch(userRoles);
        }

    }

    @Override
    public List<SysRoleDO> querySysRole(SysRoleQueryDTO page) {
        Sort sort = SortHelper.buildSort(page);
        return sysRoleDao.findAll(sort);
    }
}
